﻿using System;
using System.Collections.Generic;
using UnityEngine;

public class USTimelineObserver : USTimelineBase
{
    public List<USObserverKeyframe> baseStates = new List<USObserverKeyframe>();
    private USObserverKeyframe currentlyActiveKeyframe;
    [SerializeField, Obsolete("keyframes已过期, 请使用observerKeyframes")]
    public List<USTimelineObserverKeyframe> keyframes = new List<USTimelineObserverKeyframe>();
    [SerializeField]
    public List<USObserverKeyframe> observerKeyframes = new List<USObserverKeyframe>();

    private void AddDefaultCamerasToBaseState()
    {
        USObserverKeyframe keyframe = ScriptableObject.CreateInstance<USObserverKeyframe>();
        Camera[] cameraArray = UnityEngine.Object.FindObjectsOfType(typeof(Camera)) as Camera[];
        foreach (Camera camera in cameraArray)
        {
            keyframe.observer = this;
            keyframe.camera = camera;
            keyframe.prevActiveState = true;
            this.AddToBaseStates(keyframe);
        }
    }

    public USObserverKeyframe AddKeyframe(float fireTime, Camera camera)
    {
        USObserverKeyframe item = ScriptableObject.CreateInstance<USObserverKeyframe>();
        item.observer = this;
        item.FireTime = fireTime;
        item.camera = camera;
        this.observerKeyframes.Add(item);
        this.observerKeyframes.Sort(new Comparison<USObserverKeyframe>(this.KeyframeComparer));
        return item;
    }

    private void AddToBaseStates(USObserverKeyframe keyframe)
    {
        if (keyframe != null)
        {
            bool flag = false;
            foreach (USObserverKeyframe keyframe2 in this.baseStates)
            {
                if (keyframe2.camera == keyframe.camera)
                {
                    flag = true;
                }
            }
            if (!flag)
            {
                this.baseStates.Add(keyframe);
            }
        }
    }

    public void FireKeyframe(USObserverKeyframe keyframe)
    {
        if ((keyframe != null) && !keyframe.fired)
        {
            this.RevertKeyframe(this.currentlyActiveKeyframe);
            this.currentlyActiveKeyframe = keyframe;
            this.currentlyActiveKeyframe.fired = true;
            Camera camera = this.currentlyActiveKeyframe.camera;
            if (camera != null)
            {
                this.currentlyActiveKeyframe.prevActiveState = camera.gameObject.active;
                camera.gameObject.active = true;
                foreach (Camera camera2 in Camera.allCameras)
                {
                    if ((camera2 != null) && (camera2 != camera))
                    {
                        camera2.gameObject.active = false;
                    }
                }
            }
        }
    }

    private int KeyframeComparer(USObserverKeyframe a, USObserverKeyframe b)
    {
        return a.FireTime.CompareTo(b.FireTime);
    }

    private void OnEnable()
    {
        this.baseStates.Clear();
    }

    public override void PauseTimeline()
    {
    }

    public override void Process(float sequencerTime)
    {
        foreach (USObserverKeyframe keyframe in this.observerKeyframes)
        {
            if ((keyframe != null) && ((keyframe.FireTime < sequencerTime) && !keyframe.fired))
            {
                this.FireKeyframe(keyframe);
            }
        }
        if (((this.currentlyActiveKeyframe != null) && (this.currentlyActiveKeyframe.FireTime > sequencerTime)) && this.currentlyActiveKeyframe.fired)
        {
            this.RevertKeyframe(this.currentlyActiveKeyframe);
            this.currentlyActiveKeyframe = null;
            this.RevertToBaseState();
            this.Process(sequencerTime);
        }
    }

    public void RemoveKeyframe(USObserverKeyframe keyframe)
    {
        if ((keyframe != null) && this.observerKeyframes.Contains(keyframe))
        {
            if (this.currentlyActiveKeyframe == keyframe)
            {
                this.RevertKeyframe(this.currentlyActiveKeyframe);
                this.currentlyActiveKeyframe = null;
            }
            this.observerKeyframes.Remove(keyframe);
        }
    }

    public override void ResumeTimeline()
    {
    }

    public void RevertKeyframe(USObserverKeyframe keyframe)
    {
        if ((keyframe != null) && keyframe.fired)
        {
            keyframe.fired = false;
            if (keyframe.camera != null)
            {
                keyframe.camera.gameObject.active = keyframe.prevActiveState;
            }
        }
    }

    public void RevertToBaseState()
    {
        foreach (USObserverKeyframe keyframe in this.baseStates)
        {
            if ((keyframe != null) && (keyframe.camera != null))
            {
                keyframe.camera.gameObject.active = keyframe.prevActiveState;
            }
        }
        this.baseStates.Clear();
        this.AddDefaultCamerasToBaseState();
    }

    public void SetKeyframeCamera(USObserverKeyframe keyframe, Camera camera)
    {
        keyframe.camera = camera;
    }

    public override void StartTimeline()
    {
        this.baseStates.Clear();
        this.AddDefaultCamerasToBaseState();
    }

    public override void StopTimeline()
    {
        this.currentlyActiveKeyframe = null;
        for (int i = this.observerKeyframes.Count - 1; i >= 0; i--)
        {
            this.RevertKeyframe(this.observerKeyframes[i]);
        }
        this.RevertToBaseState();
    }

    public USObserverKeyframe CurrentlyActiveKeyframe
    {
        get
        {
            return this.currentlyActiveKeyframe;
        }
    }

    [Serializable, Obsolete("USTimelineObserverKeyframe is Obsolete, please us USObserverKeyframe instead")]
    public class USTimelineObserverKeyframe
    {
        public Camera camera;
        public bool fired;
        [SerializeField]
        private float fireTime;
        public USTimelineObserver observer;
        public bool prevActiveState;

        public float FireTime
        {
            get
            {
                return this.fireTime;
            }
            set
            {
                this.fireTime = Mathf.Min(Mathf.Max(value, 0f), this.observer.Sequence.Duration);
            }
        }
    }
}

